package com.qf.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.*;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import com.qf.common.exception.ShopException;

import java.util.Calendar;
import java.util.Map;
import java.util.Set;

public class JwtUtils {
    private static String sign = "2009-商城签名";

    //map为传过来的token中存入的用户信息
    //time为超时时间
    public static String createToken(Map<String, String> map, Integer time) {
        //创建
        JWTCreator.Builder builder = JWT.create();

        //获取calendar的实例
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND, time);
        //设置超时时间
        builder.withExpiresAt(instance.getTime());
        //设置负载用户的数据信息
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            builder.withClaim(entry.getKey(), entry.getValue());
        }

        //设置签名
        String token = builder.sign(Algorithm.HMAC256(JwtUtils.sign));

        return token;
    }

    //验证token
    public static DecodedJWT checkToken(String token) throws ShopException {
        //设置签名
        Verification require = JWT.require(Algorithm.HMAC256(sign));
        //验证token,如果不一致就抛出异常，自定义异常
        try {
            return require.build().verify(token);

        } catch (TokenExpiredException e) {
            throw new ShopException(1001, "token过期");
        } catch (SignatureVerificationException e) {
            throw new ShopException(1002, "用户签名不一致");
        } catch (InvalidClaimException e) {
            throw new ShopException(1003, "payload数据有误");
        } catch (AlgorithmMismatchException e) {
            throw new ShopException(1004, "签名算法不一致");
        } catch (JWTVerificationException e) {
            throw new ShopException(1005, "token校验失败了");
        }
    }

    //校验成功后从token获取数据,DecodedJWT:校验的结果
    public static String getWithClaim(String key, DecodedJWT decodedJWT) {
        return decodedJWT.getClaim(key).asString();
    }

}
